// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import { e_roomState, I_gameData, I_gamePlayer, PlayerInfo } from "../common/playerInfo";
import { UiMgr, uiPanel } from "../common/uiMgr";
import { CardPrefab } from "./cardPrefab";
import { CardSelect } from "./cardSelect";
import { GameOverPanel } from "./gameOverPanel";

import { cardUtil, e_card_arr_type, e_card_color, e_card_score, I_card, I_cardRes } from "../common/cardLogic";
import nakama from "../common/nakama";

import {OpCode} from "../common/messages"

const { ccclass, property } = cc._decorator;



@ccclass
export class GamePanel extends cc.Component {
    public static instance: GamePanel = null;

    @property(cc.Prefab)
    private cardPrefab: cc.Prefab = null;   // 卡牌prefab

    private meChairId: number = 0;      //我的座位号
    @property(cc.Node)
    private normalBtns: cc.Node = null;     // 出牌按钮
    @property(cc.Node)
    private qiangdizhuBtns: cc.Node = null;     // 抢地主按钮

    private state: e_roomState = e_roomState.decideDizhu;   // 房间状态
    private nowTime: number = 0;        // 当前倒计时
    private nowTimeInt: number = -1;
    private nowChairId: number = 0;     // 当前决策者
    private dipai: I_card[] = [];       // 底牌
    private players: { [chairId: number]: { "info": I_gamePlayer, "node": cc.Node } } = {};
    private playerNum = 0;
    private qiangDizhuMaxScore: number = 0;     // 抢地主出现的最大分
    private dizhuChairId: number = 0;       // 地主座位号
    private lastPlayChairId: number = 0;    // 上个出了牌的座位号
    private nowClockLabel: cc.Label = null;    // 当前计时钟
    private isGameOver: boolean = false;

    private firstCardInRound: I_card = null;

    private masterColor: e_card_color = e_card_color.flower;


    private myCards: I_card[] = [];
    private playedCards: I_card[] = [];  //打出去的牌集合
    private initCards: I_card[] = [];

    delMyCard(id: number) {
        this.scheduleOnce(function() {
            // 这里的 this 指向 component

            let node: cc.Node = this.node.getChildByName(id.toString());
            cc.tween(node)
                // .to(1, {opacity: 0})
                .to(0.2, { position: cc.v3(0, node.y + 100, 0)})
                .call(() => {
                    console.log(node)
                    // node.destroy()
                    // let that = this;
                    this.myCards = this.myCards.filter((card: I_card) => {
                        
                        // this.playedCards.push(card)
                        // console.log(this.playedCards)
                        return card.id != id
                        
                    })
                    
                    console.log(this.playedCards)
                    this.sortMyCards(this.myCards)
                    this.sortMyCards(this.playedCards)
                }, node)
                // .by(1, { scale: 0.5 })
                .start()
                
            // console.log(node.name)
            // node.destroy();
        }, 5);
    }

    sortMyCards(cards: I_card[], posy = -200) {
        let myCardsLen = cards.length
        cards.forEach(function(value: I_card, index: number) {
            let tmpNode: cc.Node = this.node.getChildByName(value.id.toString());
            let pos_x = (index - (myCardsLen >> 1)) * 20
            tmpNode.getComponent(CardPrefab).move(pos_x, posy);

            // this.myCards.push({
            //     id: value,
            //     color: e_card_color.red,
            //     score: e_card_score.c2
            // })

            // this.newCardWithPos({
            //     id: value,
            //     color: e_card_color.red,
            //     score: e_card_score.c2
            // }, meCardNode, {x:value, y:0}, value);
        }, this);
    }

    onLoad() {
        GamePanel.instance = this;
    }

    start() {

        // network.addHandler(cmd.onQiangDizhu, this.svr_onQiangDizhu, this);
        // network.addHandler(cmd.onPlayCard, this.svr_onPlayCard, this);
        // network.addHandler(cmd.onDealCard, this.svr_onDealCard, this);
        // network.addHandler(cmd.onGameOver, this.svr_onGameOver, this);
        // network.addHandler(cmd.onSetMasterColor, this.svr_onSetMasterColor, this);

        
        nakama.addHandler(OpCode.DEAL, this.svr_onDealCard, this);//发牌
        nakama.addHandler(OpCode.ON_ROB_HOST, this.svr_onQiangDizhu, this);//抢主家
        nakama.addHandler(OpCode.ONPLAY, this.svr_onPlayCard, this);
        nakama.addHandler(OpCode.ON_PLAY_ILLEGAL, this.svr_onPlayIllegal, this);
        nakama.addHandler(OpCode.ON_POINT, this.svr_onPoint, this);
        nakama.addHandler(OpCode.ON_GAME_OVER, this.svr_onGameOver, this);

        this.init();
    }

    
    init() {
        // let data = PlayerInfo.gameData;
        // console.log("data:"+ JSON.stringify(data))
        this.initCards = cardUtil.genCards(1, false);
        let userCards = this.initCards.slice(0, 10)

        let player: I_gamePlayer = {
            uid: '',
            nickname: '',
            gold: 900,
            chairId: 0,
            cards: userCards,
            lastCards: []
        }
        let data: I_gameData = {
            state: e_roomState.normal,
            nowChairId: 0,
            nowTime: 0,
            dipai: [],
            dizhuChairId: 0,
            dizhuMaxScore: 20,
            lastPlayChairId: 0,
            players: [player],
            masterColor: e_card_color.black,
        }
        this.state = data.state;
        this.nowTime = data.nowTime;
        this.nowChairId = data.nowChairId;
        this.qiangDizhuMaxScore = data.dizhuMaxScore;
        this.dizhuChairId = data.dizhuChairId;
        this.lastPlayChairId = data.lastPlayChairId;
        this.dipai = data.dipai;
        this.masterColor = e_card_color.flower;//data.masterColor;//
        console.log('master color = ' + this.masterColor)

        this.playerNum = data.players.length;

        let card_test: I_card = {
            id: 1,
            color: e_card_color.red,
            score: e_card_score.c2
        };
        let meCardNode = this.node;
        this.initCards.forEach(function(card: I_card) {
            this.myCards.push(card)

            this.newCardWithPos(card, meCardNode, {x:card.id, y:0}, card.id);
        }, this);
        // [-5,-4,-3,-2,-1,0,1,2,3,4,5].forEach(function(value){
        //     console.log(value)
        //     this.newCardWithPos(card_test, meCardNode, {x:value, y:0}, value);
        // }, this);
        

        

        this.delMyCard(1);
        

        

        for (let one of data.players) {
            console.log(`one.uid: ` + one.uid)
            if (one.uid === PlayerInfo.uid) {
                this.meChairId = one.chairId;
                break;
            }
        }
        for (let one of data.players) {
            let node = this.node.getChildByName("player" + this.getNodeId(one.chairId));
            console.log("one.chairId:" + one.chairId)
            this.players[one.chairId] = { "info": one, "node": node };

            node.getChildByName("left").getComponent(cc.Label).string = "x" + one.cards.length;
            if (one.chairId == this.meChairId) {
                cc.find("meInfo/nickname", this.node).getComponent(cc.Label).string = one.nickname;
                cc.find("meInfo/gold", this.node).getComponent(cc.Label).string = "金币:" + one.gold;
            } else {
                cc.find("info/nickname", node).getComponent(cc.Label).string = one.nickname;
                cc.find("info/gold", node).getComponent(cc.Label).string = "金币:" + one.gold;
            }

            let cardsNode = node.getChildByName("cards");
            delChildren(cardsNode);
            if (this.state === e_roomState.normal) {
                if (one.lastCards.length === 0) {
                    node.getChildByName("noCards").active = true;
                } else {
                    node.getChildByName("noCards").active = false;
                    for (let card of one.lastCards) {
                        this.newCard(card, cardsNode);
                    }
                }
            } else {
                node.getChildByName("noCards").active = false;
            }


            if (one.chairId === this.nowChairId) {
                let clock = node.getChildByName("clock");
                clock.active = true;
                this.nowClockLabel = clock.children[0].getComponent(cc.Label);
                delChildren(cardsNode);
                node.getChildByName("noCards").active = false;
            } else {
                node.getChildByName("clock").active = false;
            }
        }

        if (this.state === e_roomState.normal) {
            this.players[this.dizhuChairId].node.getChildByName("dizhu").active = true;

            let dipaiParent = this.node.getChildByName("dipai");
            delChildren(dipaiParent);
            for (let one of this.dipai) {
                this.newCard(one, dipaiParent);
            }
        }

        let sevensParent = this.node.getChildByName("sevens");
        let sevens = sevensParent.children
        for (let s of sevens) {
            // s.active = false;
        }

        // let meCardNode = CardSelect.instance.node;
        // delChildren(meCardNode);
        // CardSelect.instance.reset();
       

        if (this.meChairId === this.nowChairId) {
            if (this.state === e_roomState.decideDizhu) {
                this.meTo_qiangDizhu();
            } else {
                this.qiangdizhuBtns.active = false;
                this.normalBtns.active = true;
                this.players[this.meChairId].node.getChildByName("noCards").active = false;
                delChildren(this.players[this.meChairId].node.getChildByName("cards"));
            }
        } else {
            this.qiangdizhuBtns.active = false;
            this.normalBtns.active = false;
        }

        // CardSelect.instance.setEnable(userCards, false)
    }

    /**
     * 是个循环，座椅id要对应界面上的node id，按顺序摆放，形成个圈
     * @param chairId 
     * @returns 
     */
    private getNodeId(chairId: number) {
        let id = chairId - this.meChairId;
        if (id < 0) {
            id += 2;
        }
        return id;
    }

    private getNextChairId(chairId: number) {
        if (chairId === 2) {
            return 0;
        } else {
            return chairId + 1;
        }
    }


    private newCard(card: I_card, parent: cc.Node, cb: any = null) {
        let tmpNode = cc.instantiate(this.cardPrefab);
        tmpNode.parent = parent;
        tmpNode.getComponent(CardPrefab).init_with_cb(card, cb);
    }

    private newCardWithPos(card: I_card, parent: cc.Node, position: {x: number, y: number}, index: number) {
        let tmpNode = cc.instantiate(this.cardPrefab);
        tmpNode.parent = parent;
        // tmpNode.getComponent(CardPrefab).init_with_cb(card, cb);
        let card_prefab: CardPrefab = tmpNode.getComponent(CardPrefab).init_with_pos(card, position, index);
        let that = this;
        card_prefab.onTouchEnd(function(e) {

            // this.delMyCard(e.id);

            e.move(e.node.x, e.node.y + 100);
            let card = that.myCards.find((card: I_card) => {
                return card.id == e.id
            })

            that.playedCards.push(card)

            that.myCards = that.myCards.filter((card: I_card) => {
                // console.log(x, id)
                
                return card.id != e.id
            })
            console.log(that.playedCards)
            that.sortMyCards(that.playedCards, -100)
            that.sortMyCards(that.myCards)
        })
        
    }

    update(dt: number) {
        if (this.isGameOver) {
            return;
        }
        this.nowTime -= dt * 1000;
        let tmpInt = Math.floor(this.nowTime / 1000);
        if (tmpInt !== this.nowTimeInt && tmpInt >= 0) {
            this.nowTimeInt = tmpInt;
            this.nowClockLabel.string = tmpInt.toString();
        }
    }

    private btn_qiangDizhu(touch, scoreStr: string) {
        let score = parseInt(scoreStr);
        // network.sendMsg(cmd.game_main_qiangDizhu, { "score": score });
    }

    private btn_playCard() {
        let ids = CardSelect.instance.getSelectedCards();
        if (ids.length === 0) {
            return;
        }
        nakama.playCards(ids)
        // network.sendMsg(cmd.game_main_playCard, { "ids": ids });
    }

    /**
     * 
     * @param event 
     * @param customEventData color
     */
    private btn_setMasterColor(event: Event, customEventData: string) {
        // let node = event.target as Node

        let color = parseInt(customEventData);
        console.log("color = " + color)
        // network.sendMsg(cmd.game_main_setMasterColor, { "color":  color});
    }

    private btn_playNoCard() {
        console.log('btn_playNoCard');
        //测试增加显示的牌
        let meCardNode = CardSelect.instance.node;
        this.newCard({ "id": 100, "color": e_card_color.black, "score": e_card_score.K }, meCardNode)
        if (this.lastPlayChairId === this.meChairId) {
            return;
        }
        // network.sendMsg(cmd.game_main_playCard, { "ids": [] });
    }

    private meTo_qiangDizhu() {
        this.qiangdizhuBtns.active = true;
        this.normalBtns.active = false;
        if (this.qiangDizhuMaxScore === 1) {
            this.qiangdizhuBtns.getChildByName("1").active = false;
        } else if (this.qiangDizhuMaxScore === 2) {
            this.qiangdizhuBtns.getChildByName("1").active = false;
            this.qiangdizhuBtns.getChildByName("2").active = false;
        }
    }

    /**
     * 
     * @param id 当前牌的ID
     */
    private add_card_from_dipai_to_user(id: number) {
        // network.sendMsg(cmd.game_main_addCardToUser, { "color":  color});
    }

    private svr_onQiangDizhu(msg: { "score": number, "dizhuChairId": number }) {
        this.players[this.nowChairId].node.getChildByName("clock").active = false;
        if (this.nowChairId === this.meChairId) {
            this.qiangdizhuBtns.active = false;
        }
        if (msg.dizhuChairId !== -1) {
            this.state = e_roomState.normal;
            this.dizhuChairId = msg.dizhuChairId;
            this.nowChairId = msg.dizhuChairId;
            this.nowTime = 20 * 1000;
            this.lastPlayChairId = this.dizhuChairId;

            let p = this.players[this.nowChairId];
            // console.log(JSON.stringify(p.info))
            // p.info.cards.push(...this.dipai);
            p.node.getChildByName("left").getComponent(cc.Label).string = "x" + p.info.cards.length;
            p.node.getChildByName("dizhu").active = true;

            let dipaiParent = this.node.getChildByName("dipai");
            delChildren(dipaiParent);
            for (let one of this.dipai) {
                this.newCard(one, dipaiParent, );
            }

            let node = p.node.getChildByName("clock");
            node.active = true;
            this.nowClockLabel = node.children[0].getComponent(cc.Label);

            // 发完牌的时候，如果自己是主家的话，直接设置为可以出牌状态
            if (this.dizhuChairId === this.meChairId) {
                this.normalBtns.active = true;
                let cardsArr = p.info.cards;
                cardsArr.sort((a, b) => {
                    return cardUtil.show_compare(a, b, this.masterColor);
                });

                // 先屏蔽 把底牌给庄家的操作 这个是斗地主逻辑
                let meCardNode = CardSelect.instance.node;
                // for (let one of this.dipai) {
                //     this.newCard(one, meCardNode);
                // }
                for (let i = 0; i < cardsArr.length; i++) {
                    meCardNode.getChildByName(cardsArr[i].id.toString()).setSiblingIndex(i);
                }

            }
        } else {
            if (msg.score > this.qiangDizhuMaxScore) {
                this.qiangDizhuMaxScore = msg.score;
            }
            this.nowChairId = this.getNextChairId(this.nowChairId);
            console.log('nowChairId = ' + this.nowChairId)
            this.nowTime = 20 * 1000;
            let node = this.players[this.nowChairId].node.getChildByName("clock");
            node.active = true;
            this.nowClockLabel = node.children[0].getComponent(cc.Label);
            if (this.nowChairId === this.meChairId) {
                this.meTo_qiangDizhu();
            }

        }

    }

    private removeCardById(cards: I_card[], id: number) {
        for (let i = 0; i < cards.length; i++) {
            if (cards[i].id === id) {
                cards.splice(i, 1);
                break;
            }
        }
    }
    private svr_onPlayCard(msg: { "cardRes": I_cardRes, "isOver": boolean, "nowChairId": number, "roundOver": Boolean, "numberInRound": number }) {
        console.log('meChairId: ' + this.meChairId)
        console.log('nowChairId: ' + this.nowChairId)
        // let info = this.players[this.meChairId];
        let info = this.players[this.nowChairId]; // 这里应该是打牌的人的 chair id
        // console.log(info)
        // console.log(JSON.stringify(info.info))
        info.node.getChildByName("clock").active = false;
        // 如果是自己打的牌
        if (this.nowChairId === this.meChairId) {
            this.normalBtns.active = false;
        }
        let cards = msg.cardRes.cards;
        if (cards.length > 0) {
            for (let one of msg.cardRes.cards) {
                console.log("newCard:" + one.id)
                this.newCard(one, info.node.getChildByName("cards"));
            }
            for (let one of cards) {
                this.removeCardById(info.info.cards, one.id);
            }
            if (this.nowChairId === this.meChairId) {
                CardSelect.instance.delCards(cards);
            }
            this.lastPlayChairId = this.nowChairId;
            info.node.getChildByName("left").getComponent(cc.Label).string = "x" + info.info.cards.length;
        } else {
            info.node.getChildByName("noCards").active = true;
        }

        // if (!this.firstCardInRound) {
        this.firstCardInRound = msg.cardRes.cards[0];
        // console.log(JSON.stringify(this.nowChairId))
        // console.log(JSON.stringify(this.meChairId))
        if (this.nowChairId !== this.meChairId && msg.numberInRound === 1) {
            // let player = this.players[this.meChairId]
            // console.log(JSON.stringify(player.info))
            let suitableCards = cardUtil.get_suitable_cards(info.info.cards, this.masterColor, this.firstCardInRound)
            // console.log(this.masterColor)
            // console.log(this.firstCardInRound)
            // console.log(JSON.stringify(suitableCards))
            CardSelect.instance.setEnable(suitableCards, true);
        }
            
            
            
            
        // }

        // 一轮牌出完清除桌面上一轮打出的牌
        if (msg.numberInRound === this.playerNum) {
            let that = this
            this.firstCardInRound = null
            setTimeout(function() {
                for (let key in that.players) {
                    let player = that.players[key];
                    let node = player.node.getChildByName("cards")
                    delChildren(node)
                }
            }, 1000);

            CardSelect.instance.enable();
        }
        

        if (msg.isOver) {
            return;
        }
        // this.nowChairId = this.getNextChairId(this.nowChairId);
        this.nowChairId = msg.nowChairId;

        this.nowTime = 20 * 1000;
        let node = this.players[this.nowChairId].node.getChildByName("clock");
        node.active = true;
        this.nowClockLabel = node.children[0].getComponent(cc.Label);
        // delChildren(node.parent.getChildByName("cards"));
        node.parent.getChildByName("noCards").active = false;
        if (this.nowChairId === this.meChairId) {
            this.normalBtns.active = true;
        }
    }

    /**
     * 出的非法牌组
     */
    private svr_onPlayIllegal() {
        console.log("svr_onPlayIllegal")
        let info = this.players[this.meChairId];
        info.node.getChildByName("left").getComponent(cc.Label).string = "非法牌组:";
    }

    private svr_onPoint(msg: {"chairId": number, "point": number}) {
        console.log('meChairId: ' + this.meChairId)
        console.log('nowChairId: ' + this.nowChairId)
        // let info = this.players[this.meChairId];
        let info = this.players[msg.chairId];
        info.info.gold += msg.point
        info.node.getChildByName("left").getComponent(cc.Label).string = "得分:" + info.info.gold;
        // let node = info.node.
        // console.log("one.chairId:" + one.chairId)
        // this.players[one.chairId] = { "info": one, "node": node };

        // cc.find("info/gold", node).getComponent(cc.Label).string = "得分:" + info.info.gold;
    
    }

    /**
     * 发牌
     * @param msg 
     * @returns 
     */
    private svr_onDealCard(msg: { "cards": I_card[], "isOver": boolean, "nowChairId": number }) {
        console.log("svr_onDealCard = " + JSON.stringify(msg))
        let info = this.players[this.nowChairId];
        // info.node.getChildByName("clock").active = false;
        if (this.nowChairId === this.meChairId) {
            this.normalBtns.active = false;
        }
        let cards = msg.cards;
        if (cards.length > 0) {
            let meCardNode = CardSelect.instance.node;


            // for (let one of cards) {
            //     this.removeCardById(info.info.cards, one.id);
            // }
            if (msg.nowChairId === this.meChairId) {
                // CardSelect.instance.delCards(cards);
                this.players[this.meChairId].info.cards = this.players[this.meChairId].info.cards.concat(msg.cards)
                // console.log(JSON.stringify(this.players[this.meChairId].info.cards))
                let sevensParent = this.node.getChildByName("sevens");
                for (let one of msg.cards) {
                    // this.newCard(one, info.node.getChildByName("cards"));
                    this.newCard(one, meCardNode)
                    if (!this.masterColor) {
                        if (one.score === e_card_score.c7) {
                            let node = sevensParent.getChildByName(""+one.color)
                            node.active = true
                        }
                    }

                }

            }
            this.lastPlayChairId = this.nowChairId;
            info.node.getChildByName("left").getComponent(cc.Label).string = "x" + info.info.cards.length;
        } else {
            info.node.getChildByName("noCards").active = true;
        }

        if (msg.isOver) {
            return;
        }
        // this.nowChairId = this.getNextChairId(this.nowChairId);
        this.nowChairId = msg.nowChairId;

        this.nowTime = 20 * 1000;
        let node = this.players[this.nowChairId].node.getChildByName("clock");
        node.active = true;
        this.nowClockLabel = node.children[0].getComponent(cc.Label);
        // delChildren(node.parent.getChildByName("cards"));
        node.parent.getChildByName("noCards").active = false;
        // if (this.nowChairId === this.meChairId) {
        //     this.normalBtns.active = true;
        // }
    }

    private svr_onGameOver(msg: { "winChairId": number, "list": { "chairId": number, "gold": number }[] }) {
        this.isGameOver = true;
        UiMgr.showPanel(uiPanel.gameOverPanel, (node) => {
            node.getComponent(GameOverPanel).init(this.meChairId, this.dizhuChairId, msg, this.players);
        });
    }

    private svr_onSetMasterColor(msg: { "color": e_card_color, "chairId": number }) {
        // this.isGameOver = true;
        // UiMgr.showPanel(uiPanel.gameOverPanel, (node) => {
        //     node.getComponent(GameOverPanel).init(this.meChairId, this.dizhuChairId, msg, this.players);
        // });
        // this.masterColor = msg.color
        // this.nowChairId = msg.chairId

        // let sevensParent = this.node.getChildByName("sevens");
        // sevensParent.active = false
            // let sevens = sevensParent.children
            // for (let s of sevens) {
            //     s.active = false;
            // }
        this.masterColor = msg.color

        for (let key in this.players) {
            let player = this.players[key];

            player.info.cards.sort((a, b) => {
                return cardUtil.show_compare(a, b, this.masterColor);
            });

            // let node = player.node.getChildByName("cards")
            // delChildren(node)
            // console.log(player.info.cards);
            // for (let one of player.info.cards) {
            //     this.newCard(one, player.node.getChildByName("cards"));
            // }

            let meCardNode = CardSelect.instance.node;
                // for (let one of this.dipai) {
                //     this.newCard(one, meCardNode);
                // }
            for (let i = 0; i < player.info.cards.length; i++) {
                meCardNode.getChildByName(player.info.cards[i].id.toString()).setSiblingIndex(i);
            }
        }


    }

    btn_leave() {
        UiMgr.showSomeInfo("返回大厅吗", true, () => {
            // network.sendMsg(cmd.game_main_leave);
            cc.director.loadScene("main");
        });
    }

    onDestroy() {
        // network.removeThisHandlers(this);
        nakama.removeThisHandlers(this);
    }

}


function delChildren(node: cc.Node) {
    for (let one of node.children) {
        one.destroy();
    }
}


// interface I_cardRes {
//     card_arr_type: e_card_arr_type,
//     cards: I_card[],
//     score: e_card_score,
// }